package web_frame

import (
	"fmt"
	"log"
	"net/http"
	"strings"
)

// ============================================================================================

const (
	ANY = "ANY"
)

// HandlerFunc 定义处理 HTTP 请求的函数类型
type HandlerFunc func(ctx *Context)

// 路由
type router struct {
	// 存储所有路由组
	routerGroup []*routerGroup
}

// Group 用户创建新的路由组
// 在创建时会对路由组的名字进行格式化，去除多余的 "/"
func (r *router) Group(name string) *routerGroup {
	formatName := strings.Trim(name, "/")
	// 创建路由组并初始化方法集合
	routerGroup := &routerGroup{
		name:            formatName,                                           // 存储格式化后的路由组名
		handleFuncMap:   make(map[string]map[string]HandlerFunc),              // 存储路由路径与处理函数的映射
		handleMethodMap: make(map[string][]string),                            // 存储支持的 HTTP 方法及其对应的路由
		treeNode:        &treeNode{name: "/", children: make([]*treeNode, 0)}, // "/": 即根节点
	}
	// 将创建的路由组添加到路由集合中
	r.routerGroup = append(r.routerGroup, routerGroup)
	return routerGroup
}

// 路由组
type routerGroup struct {
	name            string                            // 路由组名称
	handleFuncMap   map[string]map[string]HandlerFunc // 路由 -> 方法 -> 处理器：用于支持 RESTful 风格路由
	handleMethodMap map[string][]string               // 存储 HTTP 方法及其对应的路由
	treeNode        *treeNode                         // 引入自主实现的前缀树
}

// formatURL 用于格式化路由路径，确保路径格式统一
func (group *routerGroup) formatURL(name string) string {
	// 去掉路径前后的 "/"，然后再加上一个 "/" 确保路径标准化
	formatName := strings.Trim(name, "/")
	return "/" + formatName
}

// handle 是用来处理具体路由与方法的注册
// 它将路径和 HTTP 方法的处理函数存储到路由组的映射表中
func (group *routerGroup) handle(name string, method string, handlerFunc HandlerFunc) {
	_, ok := group.handleFuncMap[name]
	if !ok {
		group.handleFuncMap[name] = make(map[string]HandlerFunc) // 如果路由名还没有对应的 map，创建一个新的
	}
	// 如果该路径已经存在该方法的处理函数，抛出异常
	_, ok = group.handleFuncMap[name][method]
	if ok {
		panic("路由重复") // 如果有重复的路由方法，抛出 panic 错误
	}
	// 将路由方法与对应的处理函数存储到路由组中
	group.handleFuncMap[name][method] = handlerFunc

	// 路径存入前缀树
	group.treeNode.AddPath(name)
}

// ANY 用于注册支持任何 HTTP 方法的路由
func (group *routerGroup) ANY(name string, handlerFunc HandlerFunc) {
	name = group.formatURL(name) // 格式化路由路径
	group.handle(name, ANY, handlerFunc)
}

// GET 用于注册处理 GET 请求的路由
func (group *routerGroup) GET(name string, handlerFunc HandlerFunc) {
	name = group.formatURL(name)
	group.handle(name, http.MethodGet, handlerFunc)
}

// POST 用于注册处理 POST 请求的路由
func (group *routerGroup) POST(name string, handlerFunc HandlerFunc) {
	name = group.formatURL(name)
	group.handle(name, http.MethodPost, handlerFunc)
}

// PUT 用于注册处理 PUT 请求的路由
func (group *routerGroup) PUT(name string, handlerFunc HandlerFunc) {
	name = group.formatURL(name)
	group.handle(name, http.MethodPut, handlerFunc)
}

// DELETE 用于注册处理 DELETE 请求的路由
func (group *routerGroup) DELETE(name string, handlerFunc HandlerFunc) {
	name = group.formatURL(name)
	group.handle(name, http.MethodDelete, handlerFunc)
}

func (group *routerGroup) Patch(name string, handlerFunc HandlerFunc) {
	name = group.formatURL(name)
	group.handle(name, http.MethodPatch, handlerFunc)
}
func (group *routerGroup) Options(name string, handlerFunc HandlerFunc) {
	name = group.formatURL(name)
	group.handle(name, http.MethodOptions, handlerFunc)
}
func (group *routerGroup) Head(name string, handlerFunc HandlerFunc) {
	name = group.formatURL(name)
	group.handle(name, http.MethodHead, handlerFunc)
}

// ========================================================================================

// Engine 引擎结构体，包含路由和处理 HTTP 请求的核心功能
type Engine struct {
	router // 嵌入路由结构体
}

// New 返回一个新的 Engine 实例
func New() *Engine {
	return &Engine{
		router: router{}, // 初始化路由
	}
}

// ServeHTTP 处理 HTTP 请求，根据请求的 URL 和方法找到相应的处理函数并执行
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	method := r.Method // 获取请求的 HTTP 方法
	fmt.Println(method)

	// 遍历所有路由组
	for _, group := range e.routerGroup {
		// group <=> 路由组名 + 子路由
		// 我们的匹配对象是：子路由[routerName]
		fullPath := SubStringLast(r.RequestURI, "/"+group.name)
		// 路由匹配
		node := group.treeNode.Find(fullPath)
		if node != nil && node.isEnd {
			// 匹配成功
			ctx := &Context{
				Writer:  w,
				Request: r,
			}
			// 如果该路由支持任何 HTTP 方法（即 "ANY"），直接执行对应的处理函数
			handle, ok := group.handleFuncMap[node.fullPath][ANY]
			if ok {
				handle(ctx) // 执行任意方法的处理函数
				return
			}

			// 如果该路由支持当前 HTTP 方法，执行对应的处理函数
			handle, ok = group.handleFuncMap[node.fullPath][method]
			if ok {
				handle(ctx) // 执行方法匹配的处理函数
				return
			}

			// 如果请求的方法不匹配路由，返回 "Method Not Allowed"
			w.WriteHeader(http.StatusMethodNotAllowed)
			fmt.Fprintf(w, "%s %s not allowed \n", r.RequestURI, method)
			return
		}
	}

	// 如果没有找到匹配的路由，返回 "Not Found"
	w.WriteHeader(http.StatusNotFound)
	fmt.Fprintf(w, "%s not found \n", r.RequestURI)
}

// Run 启动 HTTP 服务器并开始监听请求
// 调用 http.Handle 将 Engine 的 ServeHTTP 方法作为默认处理器
func (e *Engine) Run() {
	// 使用 Engine 的 ServeHTTP 方法处理所有请求
	http.Handle("/", e)

	// 启动 HTTP 服务器
	err := http.ListenAndServe(":8111", nil)
	if err != nil {
		log.Fatal(err) // 启动失败时记录错误日志
	}
}
